package dao

import (
	"context"
	"mini-app/internal/dal"
	"mini-app/internal/models"
	"time"

	"192.168.1.75/go-pkg/errorx"
	"192.168.1.75/go-pkg/helper"
)

type User struct{}

func (User) Create(ctx context.Context, query *dal.Query, openid, channelID string) (err error) {
	u := query.User
	data := models.User{}
	data.ID, _ = helper.UUID{}.String()
	data.OpenID = openid
	data.CreatedAt = time.Now().Unix()
	data.ChannelID = channelID
	data.Points = 100
	err = u.WithContext(ctx).Create(&data)
	return
}

func (User) Save(
	ctx context.Context,
	query *dal.Query,
	openid, nickName, phone string,
	gender int,
	birth, address, email, hobby, image string,
	userName, telNumber, postalCode, provinceName, cityName, countyName, streetName, detailAddress string,
) (err error) {
	u := query.User
	_, err = u.WithContext(ctx).
		Where(u.OpenID.Eq(openid)).
		Updates(&models.User{
			NickName:      nickName,
			Phone:         phone,
			Gender:        gender,
			Birth:         birth,
			Address:       address,
			Email:         email,
			Hobby:         hobby,
			Image:         image,
			UserName:      userName,
			TelNumber:     telNumber,
			PostalCode:    postalCode,
			ProvinceName:  provinceName,
			CityName:      cityName,
			CountyName:    countyName,
			StreetName:    streetName,
			DetailAddress: detailAddress,
		})
	return
}
func (User) List(ctx context.Context, query *dal.Query, id, openid, phone, nickName, channelID string,
	startTime, endTime int64, page, limit int) (
	res []*models.User, total int64, err error,
) {
	u := query.User
	tx := u.WithContext(ctx)
	if id != "" {
		tx = tx.Where(u.ID.Eq(id))
	}
	if openid != "" {
		tx = tx.Where(u.OpenID.Eq(openid))
	}
	if phone != "" {
		tx = tx.Where(u.Phone.Eq(phone))
	}
	if nickName != "" {
		tx = tx.Where(u.NickName.Like("%" + nickName + "%"))
	}
	if startTime > 0 && endTime > 0 {
		tx = tx.Where(u.CreatedAt.Between(startTime, endTime))
	}
	if channelID != "" {
		tx = tx.Where(u.ChannelID.Eq(channelID))
	}
	total, _ = tx.Count()
	if limit > 0 {
		tx = tx.Limit(limit)
	}
	if page > 0 && limit > 0 {
		tx = tx.Offset((page - 1) * limit)
	}
	res, err = tx.Find()
	return
}

func (User) UserInfo(ctx context.Context, query *dal.Query, openid, userID, phone string) (res *models.User, err error) {
	u := query.User
	tx := u.WithContext(ctx)
	if openid != "" {
		tx = tx.Where(u.OpenID.Eq(openid))
	}
	if userID != "" {
		tx = tx.Where(u.ID.Eq(userID))
	}
	if phone != "" {
		tx = tx.Where(u.Phone.Eq(phone))
	}
	res, err = tx.First()
	return
}

func (User) UpdatePhone(ctx context.Context, query *dal.Query, openid, phone string) (err error) {
	u := query.User
	tx := u.WithContext(ctx).
		Where(u.OpenID.Eq(openid))
	tx.UpdateSimple(u.Phone.Value(phone))
	return
}

func (User) UpdateChannelID(ctx context.Context, query *dal.Query, openid, channelID string) (err error) {
	u := query.User
	tx := u.WithContext(ctx).
		Where(u.OpenID.Eq(openid))
	tx.UpdateSimple(u.ChannelID.Value(channelID))
	return
}

func (User) Del(ctx context.Context, query *dal.Query, openid string) (err error) {
	u := query.User
	u.WithContext(ctx).
		Where(u.OpenID.Eq(openid)).
		Delete()
	return
}

// AddPoints 增加积分
func (User) AddPoints(ctx context.Context, query *dal.Query, openid string, points int64) error {
	u := query.User
	res, err := u.WithContext(ctx).
		Where(u.OpenID.Eq(openid)).
		UpdateSimple(u.Points.Add(points))
	if res.RowsAffected <= 0 || err != nil {
		return errorx.New("增加积分失败", -1)
	}
	return nil
}

// SubPoints 减少积分
func (User) SubPoints(ctx context.Context, query *dal.Query, openid string, points int64) error {
	u := query.User
	res, err := u.WithContext(ctx).
		Where(u.OpenID.Eq(openid)).
		Where(u.Points.Gte(points)).
		UpdateSimple(u.Points.Sub(points))
	if res.RowsAffected <= 0 || err != nil {
		return errorx.New("扣除积分失败", -1)
	}
	return nil
}
